
/**  
* @Title: RedisCacheAnnotation.java  
* @Package org.sapling.data.aop  
* @Description: TODO
* @author DcfZero  
* @date 2021年6月13日  
* @version V1.0  
*/ 
package org.sapling.data.aop;

import java.text.SimpleDateFormat;
import java.util.concurrent.TimeUnit;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.sapling.data.utils.RedisUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;

/**  
* TODO
* @ClassName: RedisCacheAnnotation  
* @author DcfZero 
* @date 2021年6月13日  
*    
*/
@Component
@ConditionalOnProperty(name = {"system.enabled-redis-cache"}, havingValue = "true")
@Aspect
public class RedisCacheAspect {
	private static final Logger log = org.slf4j.LoggerFactory.getLogger(RedisCacheAspect.class);
	
	@Autowired
	private RedisUtils redisUtils;
	
	@Pointcut("@annotation(org.sapling.data.aop.RedisCache)")
	public void cachePointCut() {}
	
	@Around("cachePointCut()")
	public Object around(ProceedingJoinPoint point) throws Throwable{
		long beginTime = System.currentTimeMillis();
		Object result = getCache(point);
		if(result == null) {
			result = point.proceed();
			setCache(point, result);
		}
		log.info("处理缓存完毕，耗时{}毫秒",System.currentTimeMillis() - beginTime);
		return result;
	}
	
	private Object getCache(ProceedingJoinPoint point) {
		MethodSignature signature = (MethodSignature) point.getSignature();
		RedisCache redisCache = signature.getMethod().getAnnotation(RedisCache.class);
		String key = redisCache.key();
		Long timeOut = redisCache.expireTime();
		TimeUnit timeUnit = redisCache.timeUnit();
		Object value = redisUtils.get(key);
		return value;
	}
	
	private void setCache(ProceedingJoinPoint point, Object value) throws Exception {
		MethodSignature signature = (MethodSignature) point.getSignature();
		RedisCache redisCache = signature.getMethod().getAnnotation(RedisCache.class);
		String key = redisCache.key();
		Long timeOut = redisCache.expireTime();
		TimeUnit timeUnit = redisCache.timeUnit();
		if(timeOut == 0) {
			redisUtils.set(key, value);
		}else {
			redisUtils.set(key, value, timeOut, timeUnit);
		}
	}
}
